home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
ev_201.zip
/
HANOI.ZIP
/
MODULE.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-03
|
16KB
|
396 lines
/*
Module : MODULE.CPP
Version : 2.0
Revision date : July 3rd, 1993
Author(s) : Remy Gendron
Description : Hanoi's towers functions file.
*/
// Headers ------------------------------------------------------------------
#include <math.h> // System's libraries
#include <stdio.h>
#include <stdlib.h>
#pragma hdrstop
#include "hanoi.hcm" // Other modules
#include "main.hpp"
#include "stdfcts.h"
#include "tdisk.hpp"
#include "tinput.hpp"
#include "tstatusline.hpp"
#include "ttower.hpp"
#include "twindow.hpp"
#include "module.hpp" // This module's header file
// --------------------------------------------------------------------------
void about () // Displays infos on this program
{
twindow huge *winptr ; // Ptr to a twindow class
input_info ii ; // User's input
winptr = new twindow ; // Creates a window
assert (winptr != NULL,"about",msg_stderr[1],1) ;
winptr->winsetpos (5,20,TRUE) ; // Displays window
winptr->winsetsize (15,40) ;
winptr->winsettitle ("A propos") ;
winptr->winsetcolors (BLUE) ;
winptr->winsethlpctx (HC_WINDOW_APROPOS) ;
winptr->winopen () ;
winptr->winwrite ("Les tours de Hanoi 2.0",2,1,2) ; // Writes infos
winptr->winwrite ("Un programme de démonstration",4,1,2) ;
winptr->winwrite ("de l'interface EasyVision 2.0!",5,1,2) ;
winptr->winwrite ("Copyright (c) 1993 par",7,1,2) ;
winptr->winwrite ("TNG SOFT",9,1,2) ;
winptr->winwrite ("The Next Generation Software",10,1,2) ;
// Creates a button
winptr->buttoncreate (12,16," Ok",13,"~ENTER~ pour continuer") ;
ii.key_code = II_NUL ;
winptr->wininput (ii) ; // Makes window alive
winptr->winclose () ; // Closes window
delete (winptr) ;
return ; // About screen has been displayed
} // End about
// --------------------------------------------------------------------------
config_info configuration // Configure the puzzle
(
config_info config // Configuration's infos
)
{
twindow huge *winptr ; // Ptr to a twindow class
input_info ii ; // User's input
char tmpstr[18] ; // To convert from integer to string
winptr = new twindow ; // Creates a window
assert (winptr != NULL,"configuration",msg_stderr[1],1) ;
winptr->winsetpos (7,20,TRUE) ; // Displays window
winptr->winsetsize (11,40) ;
winptr->winsethlpctx (HC_WINDOW_CONFIGURATION) ;
winptr->winsettitle ("Configuration") ;
winptr->winopen () ;
winptr->winwrite ("Disque(s)",2,2) ; // Field's names
winptr->winwrite ("Tige départ",2,20) ;
winptr->winwrite ("Vitesse",5,2) ;
winptr->winwrite ("Tige arrivée",5,20) ;
itoa (config.nb_disks,tmpstr,10) ; // Number of disks to be used
winptr->fieldcreate (3,2,2,2,2,"",FALSE,FALSE,tmpstr,
"Nombre de disque à utiliser (1-10)",EV_NOHLPCTX) ;
itoa (config.source,tmpstr,10) ; // Source shaft
winptr->fieldcreate (3,20,1,1,4,"123",FALSE,FALSE,tmpstr,
"Numéro de la tige de départ (1-3)",EV_NOHLPCTX) ;
itoa (config.speed,tmpstr,10) ; // Execution's speed
winptr->fieldcreate (6,2,1,1,2,"",FALSE,FALSE,tmpstr,
"Vitesse d'exécution (0-9)",EV_NOHLPCTX) ;
itoa (config.target,tmpstr,10) ; // Target shaft
winptr->fieldcreate (6,20,1,1,2,"",FALSE,FALSE,tmpstr,
"Numéro de la tige d'arrivée (1-3)",EV_NOHLPCTX) ;
// Creates some buttons
winptr->buttoncreate (9,2," Ok",II_CR,
"Accepte et sauve la configuration",EV_NOHLPCTX) ;
winptr->buttoncreate (9,29," Annule",II_ESC,
"Annule les changements",EV_NOHLPCTX) ;
ii.key_code = II_NUL ; // Makes window alive
ii = winptr->wininput (ii) ;
if (ii.key_code == II_CR) // Accepted changes
{
winptr->fieldgetasw (tmpstr,1) ; // Gets nb of disks
config.nb_disks = atoi (tmpstr) ;
if ((config.nb_disks) > 10) // Validates nb of disks
config.nb_disks = 10 ;
if ((config.nb_disks) < 1)
config.nb_disks = 1 ;
winptr->fieldgetasw (tmpstr,2) ; // Gets source
config.source = atoi (tmpstr) ;
winptr->fieldgetasw (tmpstr,4) ; // Gets target
config.target = atoi (tmpstr) ;
if (config.target == config.source) // Validates source and target
if (config.source == 1) config.target = 3 ;
else config.target = 1 ;
winptr->fieldgetasw (tmpstr,3) ; // Gets speed
config.speed = atoi (tmpstr) ;
}
winptr->winclose () ; // Closes window
delete (winptr) ;
return config ; // Configuration is updated
} // End configuration
// --------------------------------------------------------------------------
void animation // Animates the solution
(
config_info config // Configuration informations
)
{
twindow huge *winptr1 ; // Ptr to animation window
twindow huge *winptr2 ; // Ptr to status window
ttower huge *towers[3] ; // 3 ptrs to tower class
ttower huge *source ; // Source tower
ttower huge *target ; // target tower
ttower huge *temporary ; // Temporary tower
tdisk huge *disks[10] ; // 10 Ptrs to disk class
int loop ; // Counter
winptr1 = new twindow ; // Creates animation window
assert (winptr1 != NULL,"animation",msg_stderr[1],1) ;
winptr1->winsetpos (2,1) ; // Opens window
winptr1->winsetsize (20,80) ;
winptr1->winsetcolors (BLACK) ;
winptr1->winsettitle ("Animation") ;
winptr1->winsethlpctx (EV_NOHLPCTX) ;
winptr1->winopen () ;
winptr2 = new twindow ; // Create status window
assert (winptr2 != NULL,"animation",msg_stderr[1],1) ;
winptr2->winsetpos (22,1) ; // Opens window
winptr2->winsetsize (3,80) ;
winptr2->winsetcolors (BLUE) ;
winptr2->winsettitle ("Informations") ;
winptr2->winsethlpctx (EV_NOHLPCTX) ;
winptr2->winopen () ;
towers[0] = new ttower (1,17,4,BROWN,winptr1) ; // Creates 3 towers
assert (towers[0] != NULL,"animation",msg_stderr[1],1) ;
towers[1] = new ttower (2,17,29,BROWN,winptr1) ;
assert (towers[1] != NULL,"animation",msg_stderr[1],1) ;
towers[2] = new ttower (3,17,54,BROWN,winptr1) ;
assert (towers[2] != NULL,"animation",msg_stderr[1],1) ;
for (loop=1 ; loop<=3 ; loop++) // Shows them
towers[loop-1]->show () ;
source = towers[config.source-1] ; // Selects source, target and temp
target = towers[config.target-1] ;
if ((config.source != 1) && (config.target != 1))
temporary = towers[0] ;
else if ((config.source != 2) && (config.target != 2))
temporary = towers[1] ;
else temporary = towers[2] ;
winptr2->winwrite ("Placement des disques sur la tour de départ",1,1,2) ;
for (loop=1 ; loop<=config.nb_disks ; loop++) // Creates disks
{
disks[loop-1] = new tdisk (loop,2,2,winptr1) ; // Creates one disk
assert (disks[loop-1] != NULL,"animation",msg_stderr[1],1) ;
disks[loop-1]->show () ; // Shows it
disks[loop-1]->moveto (source->getrow () - 2 - source->getnbdisks (),
source->getcol (),
source->getcolor (),source->getcolor (),
config.speed) ;
source->pushdisk (disks[loop-1]) ; // Updates tower's infos
}
// Displays number of moves necessary to solve the puzzle
itoa ((int)pow (2,config.nb_disks) - 1,nbmoves,10) ;
winptr2->winclear () ;
winptr2->winwrite ("Déplacements nécessaires:",1,2) ;
winptr2->winwrite (nbmoves,1,28) ;
winptr2->winwrite ("Déplacements effectués:",1,37) ;
winptr2->winwrite ("Vitesse:",1,67) ;
statusline.display ("~+~ ou ~-~ pour changer la vitesse, "
"~Une autre touche~ pour terminer") ;
while ( kbhit() ) (void) getch () ; // Empties keyboard buffer
move_count = 0 ; // Initialises move counter
globspeed = config.speed ; // Initialises global speed variable
end_anim = FALSE ; // Initialises animation's abort flag
// Finds solution with the recursive algorithm
hanoi (config.nb_disks,source,target,temporary,winptr2) ;
pause () ; // Pauses after animation
for (loop=1 ; loop<=config.nb_disks ; loop++) // Deletes disks
delete disks[loop-1] ;
for (loop=1 ; loop<=3 ; loop++) // Deletes towers
delete towers[loop-1] ;
winptr2->winclose () ; // Closes windows
delete (winptr2) ;
winptr1->winclose () ;
delete (winptr1) ;
statusline.display () ; // Clears statusline
return ; // Animation's done
} // End animation
// --------------------------------------------------------------------------
void hanoi // Finds solution for the current configuration
(
int nb_disks, // Number of disks to move
ttower huge *source, // Moves from tower
ttower huge *target, // Moves to tower
ttower huge *temporary, // Temporary tower
twindow huge *winptr2 // Ptr to status window
)
{
anim_input () ; // Checks inputs during animation
if (end_anim == TRUE) return ; // Animation has been aborted, stops here
if (nb_disks == 1) // If last disk to move...
{
itoa (globspeed,alphaspeed,10) ;
winptr2->winwrite (alphaspeed,1,76) ;
source->popdiskto (target,globspeed) ; // Then moves it
move_count++ ; // Counts moves
itoa (move_count,nbmoves,10) ; // Shows progression
winptr2->winwrite (nbmoves,1,61) ;
return ;
}
anim_input () ; // Checks inputs during animation
if (end_anim == TRUE) return ; // Animation has been aborted, stop here...
hanoi (nb_disks-1,source,temporary,target,winptr2) ;
anim_input () ; // Checks inputs during animation
if (end_anim == TRUE) return ; // Animation has been aborted, stop here...
itoa (globspeed,alphaspeed,10) ; // Shows current animation's speed
winptr2->winwrite (alphaspeed,1,76) ;
source->popdiskto (target,globspeed) ;
move_count++ ; // Counts moves
itoa (move_count,nbmoves,10) ; // Shows progression
winptr2->winwrite (nbmoves,1,61) ;
anim_input () ; // Checks inputs during animation
if (end_anim == TRUE) return ; // Animation has been aborted, stop here...
hanoi (nb_disks-1,temporary,target,source,winptr2) ;
anim_input () ; // Checks inputs during animation
if (end_anim == TRUE) return ; // Animation has been aborted, stop here...
return ; // Solution has been found
} // End hanoi
// --------------------------------------------------------------------------
void pause () // Pauses after animation
{
twindow huge *winptr ; // Ptr to a twindow class
input_info ii ; // User's input
winptr = new twindow ; // Creates a window
assert (winptr != NULL,"pause",msg_stderr[1],1) ;
winptr->winsetpos (8,28,TRUE) ; // Displays window
winptr->winsetsize (7,24) ;
winptr->winsetcolors (RED) ;
winptr->winsettitle ("Pause") ;
winptr->winsethlpctx (HC_WINDOW_PAUSE) ;
winptr->winopen () ;
winptr->winwrite ("Animation terminée",2,1,2) ; // Displays message
winptr->buttoncreate (5,8," Ok",13,"~ENTER~ pour continuer") ;
ii.key_code = II_NUL ;
winptr->wininput (ii) ; // Makes window alive
winptr->winclose () ; // Closes window
delete (winptr) ;
return ; // A pause has been made
} // End pause
// --------------------------------------------------------------------------
void anim_input () // Checks inputs during animation
{
int inchar ; // Character returned by getch ()
if (kbhit () || input.mouse_lb_down ()) // Checks user abort/speed changes
{
inchar = II_NUL ;
if (kbhit ())
{
inchar = getch () ; // A key has been pressed, gets it...
while ( kbhit() ) (void) getch () ; // Empties keyboard buffer
}
if (inchar == '+') // Makes animation faster?
{
globspeed++ ;
if (globspeed > 9) globspeed = 9 ;
}
else
{
if (inchar == '-') // Makes animation slower?
{
globspeed-- ;
if (globspeed < 0) globspeed = 0 ;
}
else end_anim = TRUE ; // Not '+' or '-', so ends animation
}
}
return ; // Inputs have been processed
} // End anim_input
// End source file ----------------------------------------------------------